﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using InterpriseSuiteEcommerceCommon.DTO;
using InterpriseSuiteEcommerceCommon.Extensions;
using InterpriseSuiteEcommerceCommon.Tool;

namespace InterpriseSuiteEcommerceCommon.InterpriseIntegration
{
    public class DefaultShoppingCartPageLiteralRenderer : IShoppingCartHTMLLiteralRenderer
    {
        #region IShoppingCartHTMLLiteralRenderer Members

        public RenderType PageRenderType { get; set; }
        public string CustomXmlPackage { get; set; }
        public string coupon {get;set;}

        public DefaultShoppingCartPageLiteralRenderer(RenderType pageRenderType, string customXmlPackage, string couponcode = "")
        {
            this.PageRenderType = pageRenderType;
            this.CustomXmlPackage = customXmlPackage;
            this.coupon = couponcode;
        }

        public DefaultShoppingCartPageLiteralRenderer(RenderType pageRenderType, string couponcode = "")
        {
            PageRenderType = pageRenderType;
            coupon = couponcode;      
        }

        public DefaultShoppingCartPageLiteralRenderer()
        {
            PageRenderType = RenderType.ShoppingCart;
        }

        public void Render(InterpriseShoppingCart cart, ref StringBuilder output)
        {
            bool vatenabled = AppLogic.AppConfigBool("VAT.Enabled");
            bool vatInclusive = (cart.ThisCustomer.VATSettingReconciled == VatDefaultSetting.Inclusive);
            bool isFreeShipping = false;

            if (cart.SalesOrderDataset != null)
            {
                decimal subTotalChecker = cart.SalesOrderDataset.CustomerSalesOrderView[0].SubTotalRate;
                isFreeShipping = (cart.CouponIncludesFreeShipping(coupon) ||
                    (InterpriseHelper.ShippingMethodCodeBelongsToFreeShippingMethodList(cart.SalesOrderDataset.CustomerSalesOrderView[0].ShippingMethodCode) &&
                    InterpriseHelper.IsFreeShippingThresholdEnabled(subTotalChecker)));
            }

            var root = new XElement(DomainConstants.XML_ROOT_NAME);
            root.Add(new XElement("RENDERTYPE", PageRenderType.ToString().ToUpper()));
            root.Add(new XElement("VATINCLUSIVE", vatInclusive.ToStringLower()));
            root.Add(new XElement("VATENABLED", vatenabled.ToStringLower()));
            root.Add(new XElement("ISFREESHIPPING", isFreeShipping.ToStringLower()));

            if (cart.IsEmpty())
            {
                string cartEmptyText = string.Empty;
                if (cart.CartType == CartTypeEnum.ShoppingCart)
                {
                    var t1 = new Topic("EmptyCartText", cart.ThisCustomer.LocaleSetting, cart.SkinID, null);
                    output.Append(t1.Contents);
                }

                if (cart.CartType == CartTypeEnum.WishCart)
                {
                    var t1 = new Topic("EmptyWishListText", cart.ThisCustomer.LocaleSetting, cart.SkinID, null);
                    output.Append(t1.Contents);
                }

                root.Add(new XElement("EMPTY_CART_TEXT", cartEmptyText));
            }
            else
            {
                bool showPicsInCart = AppLogic.AppConfigBool("ShowPicsInCart");
                bool showLinkBack = AppLogic.AppConfigBool("LinkToProductPageInCart");
                bool hideUnitMeasure = AppLogic.AppConfigBool("HideUnitMeasure");
                bool showShipDateInCart = AppLogic.AppConfigBool("ShowShipDateInCart");
                bool showStockHints = AppLogic.AppConfigBool("ShowStockHints");
               
                //root.Add(new XElement("SHOPPINGCART_HEADER_TEXT", AppLogic.GetString("mobile.shoppingcart.cs.1", cart.SkinID, cart.ThisCustomer.LocaleSetting)));
                root.Add(new XElement("SKINID", cart.SkinID));
                root.Add(new XElement("HASCOUPON", (!coupon.IsNullOrEmptyTrimmed()).ToStringLower()));
                root.Add(new XElement("SHOWSTOCKHINTS", showStockHints.ToStringLower()));
                root.Add(new XElement("SHOWSHIPDATEINCART", showShipDateInCart.ToStringLower()));

                foreach (CartItem cartItem in cart.CartItems)
                {
                    var xmlcartItem = new XElement("CART_ITEMS");
                    xmlcartItem.Add(new XElement("CART_ITEM_ID", cartItem.m_ShoppingCartRecordID));
                    xmlcartItem.Add(new XElement("ITEMTYPE", cartItem.ItemType));
                    xmlcartItem.Add(new XElement("ISOUTOFSTOCK", cartItem.IsOutOfStock.ToStringLower()));
                    xmlcartItem.Add(new XElement("CARTSTATUS", cartItem.Status));
                    xmlcartItem.Add(new XElement("ALLOCQTY", cartItem.m_AllocatedQty));
                    xmlcartItem.Add(new XElement("ITEMCODE", cartItem.ItemCode));

                    var reserveCol = cart.GetReservation(cartItem.ItemCode);
                    xmlcartItem.Add(new XElement("RESERVECOL", reserveCol.Count()));

                    string productLinkHref = InterpriseHelper.MakeItemLink(cartItem.ItemCode);
                    string displayName = cartItem.DisplayName.ToHtmlEncode();
                    xmlcartItem.Add(new XElement("PRODUCTLINKNAME", displayName));
                    xmlcartItem.Add(new XElement("LINKBACK", showLinkBack.ToStringLower()));

                    //Add this item to the root.
                    root.Add(xmlcartItem);

                    switch (cartItem.ItemType)
                    {
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP:

                        #region "ITEM_TYPE_MATRIX_ITEM"
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM:

                            using (var con = DB.NewSqlConnection())
                            {
                                con.Open();
                                using (var reader = DB.GetRSFormat(con, String.Format("SELECT ItemCode FROM InventoryMatrixItem with (NOLOCK) WHERE MatrixItemCode = {0}", DB.SQuote(cartItem.ItemCode))))
                                {
                                    if (reader.Read())
                                    {
                                        productLinkHref = InterpriseSuiteEcommerceCommon.InterpriseHelper.MakeItemLink(DB.RSField(reader, "ItemCode"));
                                    }
                                }
                            }

                            if (showLinkBack && !cartItem.IsCheckoutOption)
                            {
                                xmlcartItem.Add(new XElement("ISCHECKOUTOPTION", false));
                                xmlcartItem.Add(new XElement("PRODUCTLINKHREF", productLinkHref));
                            }

                            var matrixDetails = new StringBuilder();
                            var matrixAttributes = AppLogic.GetMatrixItemAttributes(cartItem.ItemCode, Customer.Current.LanguageCode);

                            //Iterate through matrix attributes and append it to the details
                            matrixAttributes.ForEach(item =>
                            {
                                matrixDetails.AppendFormat("&nbsp;&nbsp;{0}:{1}<br />", Security.HtmlEncode(item.AttributeValue), Security.HtmlEncode(item.AttributeValueDescription));
                            });
                            xmlcartItem.Add(new XElement("MatrixDetails", matrixDetails.ToString()));

                            bool hasRegistryItem = (cartItem.RegistryItemCode.HasValue && cartItem.GiftRegistryID.HasValue);
                            xmlcartItem.Add(new XElement("ISREGISTRYITEM", hasRegistryItem.ToStringLower()));
                            if (hasRegistryItem)
                            {
                                xmlcartItem.Add(new XElement("REGISTRYITEMQUANTITY", cartItem.RegistryItemQuantity.Value.ToString("00")));
                                xmlcartItem.Add(new XElement("ISREGISTRYITEMHASCONFLICT", cartItem.HasRegistryItemQuantityConflict().ToStringLower()));
                            }

                            break;

                        #endregion

                        #region "ITEM_TYPE_KIT"
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT:

                            if (showLinkBack && !cartItem.IsCheckoutOption)
                            {
                                xmlcartItem.Add(new XElement("ISCHECKOUTOPTION", false));
                                xmlcartItem.Add(new XElement("PRODUCTLINKHREF", productLinkHref));
                            }

                            var kitItems = new XElement("KIT_ITEMS");
                            string href = InterpriseSuiteEcommerceCommon.InterpriseHelper.MakeItemLink(cartItem.ItemCode) + "?kcid={0}".FormatWith(cartItem.Id.ToString());
                            kitItems.Add(new XElement("KIT_EDIT_HREF", href));

                            bool isCurrencyIncludedForInventorySelling = InterpriseHelper.IsCurrencyIncludedForInventorySelling(cart.ThisCustomer.CurrencyCode);
                            // Special case 2 
                            //  Currency is added in Inventory Selling Currency late
                            //  after the kit has been created, ideally the kit should regenerate kit pricing for this currency
                            //  but for the meantime, we should handle this by looking into the home currency
                            bool currencyIsIncludedInInventorySellingCurrencyButHasNoKitPricingDetailYetForThisItem =
                            InterpriseHelper.CurrencyIsIncludedInInventorySellingCurrencyButHasNoKitPricingDetailYet(cart.ThisCustomer.CurrencyCode, cartItem.ItemCode);

                            // read the records from the EcommerceKitCart table...
                            var lstKitDetails = AppLogic.GetKitDetail(cartItem.ItemCode,
                                                                      CommonLogic.IIF((isCurrencyIncludedForInventorySelling && !currencyIsIncludedInInventorySellingCurrencyButHasNoKitPricingDetailYetForThisItem), cart.ThisCustomer.CurrencyCode, Currency.GetHomeCurrency()),
                                                                      cart.ThisCustomer.LocaleSetting,
                                                                      cart.ThisCustomer.CustomerCode,
                                                                      cartItem.Id, 
                                                                      cart.ThisCustomer.ContactCode);

                            lstKitDetails.ForEach(item => {
                                kitItems.Add(new XElement("KITITEM", Security.HtmlEncode(string.Format("({0}) {1}", Localization.ParseLocaleDecimal(item.Quantity, cart.ThisCustomer.LocaleSetting).TryParseInt().Value, Security.HtmlEncode(item.Name)))));
                            });
                            xmlcartItem.Add(kitItems);

                            hasRegistryItem = (cartItem.RegistryItemCode.HasValue && cartItem.GiftRegistryID.HasValue);
                            xmlcartItem.Add(new XElement("ISREGISTRYITEM", hasRegistryItem.ToStringLower()));
                            if (hasRegistryItem)
                            {
                                xmlcartItem.Add(new XElement("REGISTRYITEMQUANTITY", cartItem.RegistryItemQuantity.Value.ToString("00")));
                                xmlcartItem.Add(new XElement("ISREGISTRYITEMHASCONFLICT", cartItem.HasRegistryItemQuantityConflict().ToStringLower()));
                            }

                            break;
                        #endregion

                        #region "STOCK"
                        default:
                            if (showLinkBack)
                            {
                                if (!cartItem.IsCheckoutOption)
                                {
                                    xmlcartItem.Add(new XElement("ISCHECKOUTOPTION", false));
                                    xmlcartItem.Add(new XElement("PRODUCTLINKHREF", productLinkHref));
                                }
                                else
                                {
                                    //checkout options should only display a popup and not go to a product page
                                    //output.AppendFormat(
                                    //    "<a onclick=\"popuporderoptionwh('Order Option {0}',{1},650,550,'yes');\" href=\"javascript:void(0);\"><b>{0}</b></a><br>",
                                    //    Security.HtmlEncode(cartItem.DisplayName),
                                    //    cartItem.ItemCounter.ToString()
                                    //);
                                }

                                hasRegistryItem = (cartItem.RegistryItemCode.HasValue && cartItem.GiftRegistryID.HasValue);
                                xmlcartItem.Add(new XElement("ISREGISTRYITEM", hasRegistryItem.ToStringLower()));
                                if (hasRegistryItem)
                                {
                                    xmlcartItem.Add(new XElement("REGISTRYITEMQUANTITY", cartItem.RegistryItemQuantity.Value.ToString("00")));
                                    xmlcartItem.Add(new XElement("ISREGISTRYITEMHASCONFLICT", cartItem.HasRegistryItemQuantityConflict().ToStringLower()));
                                }

                            }
                            break;
                        #endregion
                    }

                    #region "Product Picture"

                    if (showPicsInCart)
                    {
                        xmlcartItem.Add(new XElement("SHOWPICSINCART", true));
                        var img = ProductImage.Locate("product", cartItem.ItemCounter, "icon");
                        if (null != img)
                        {
                            string seTitle = "";
                            string seAltText = "";
                            string itemCode = itemCode = InterpriseHelper.GetInventoryItemCode(cartItem.ItemCounter);
                            AppLogic.GetSEImageAttributes(itemCode, "ICON", AppLogic.GetLanguageCode(cart.ThisCustomer.LocaleSetting), ref seTitle, ref seAltText);

                            xmlcartItem.Add(new XElement("PRODUCTIMAGEPATH", img.src));
                            xmlcartItem.Add(new XElement("PRODUCTIMAGETITLE", seTitle));
                            xmlcartItem.Add(new XElement("PRODUCTIMAGEALT", seAltText));
                        }
                    }

                    #endregion

                    #region "Multiple Address"

                    xmlcartItem.Add(new XElement("HAS_MULTIPLE_ADDRESSES", cart.HasMultipleShippingAddresses().ToStringLower()));

                    /*************** multiple address **********************/
                    if (cart.HasMultipleShippingAddresses() && !cartItem.IsDownload)
                    {
                        xmlcartItem.Add(new XElement("ITEMISDOWNLOAD", false));
                        var adr = new Address();
                        bool includename = true;

                        string shippingName = string.Empty;
                        if (cartItem.m_ShippingAddressID == cart.ThisCustomer.PrimaryShippingAddressID && !cartItem.GiftRegistryID.HasValue)
                        {
                            adr.LoadByCustomer(cart.ThisCustomer, AddressTypes.Shipping, cartItem.m_ShippingAddressID, cartItem.GiftRegistryID);
                            shippingName = AppLogic.GetString("account.aspx.10", cart.SkinID, cart.ThisCustomer.LocaleSetting);
                        }
                        else if (cartItem.m_ShippingAddressID == cart.ThisCustomer.PrimaryBillingAddressID)
                        {
                            adr.LoadByCustomer(cart.ThisCustomer, AddressTypes.Billing, cartItem.m_ShippingAddressID, cartItem.GiftRegistryID);
                            shippingName = AppLogic.GetString("account.aspx.8", cart.SkinID, cart.ThisCustomer.LocaleSetting);
                        }
                        else
                        {
                            //specify the name if the shipping address is not primary
                            adr.LoadByCustomer(cart.ThisCustomer, AddressTypes.Shipping, cartItem.m_ShippingAddressID, cartItem.GiftRegistryID);
                            shippingName = adr.Name;
                            includename = false;
                        }

                        xmlcartItem.Add(new XElement("SHIP_ITEM_TO_VALUE", shippingName));
                        xmlcartItem.Add(new XElement("SHIP_ITEM_DETAIL", adr.DisplayString(false, false, includename, "")));
                        xmlcartItem.Add(new XElement("SHIPING_METHOD_VALUE", cartItem.m_ShippingMethod));
                    }

                    #endregion

                    #region "Stock Hints"

                    if (showStockHints && showShipDateInCart)
                    {
                        string localizedQty = Localization.ParseLocaleDecimal(cartItem.m_AllocatedQty, cart.ThisCustomer.LocaleSetting);
                        bool isCBNItem = (cartItem.IsCBN && !cartItem.CBNItemID.IsNullOrEmptyTrimmed()) ? true : false;
                        decimal freeStock = cartItem.FreeStock;
                        bool isDropShip = cartItem.IsDropShip;

                        xmlcartItem.Add(new XElement("ALLOCATEDQTY", localizedQty));
                        xmlcartItem.Add(new XElement("ISCBNITEM", isCBNItem));
                        xmlcartItem.Add(new XElement("ISDROPSHIP", isDropShip));

                        decimal ordered = cartItem.AssociatedLineItemRow.QuantityOrdered;
                        decimal totalReserved = cartItem.AssociatedLineItemRow.QuantityReserved;
                        decimal notAvailableQty = decimal.Zero;

                        if (!cartItem.IsCBN)
                        {
                            notAvailableQty = cartItem.AssociatedLineItemRow.QuantityOrdered - (cartItem.m_AllocatedQty + cartItem.AssociatedLineItemRow.QuantityReserved);
                            xmlcartItem.Add(new XElement("NOTAVAILABLEQTYWITHRESERVATION", Localization.ParseLocaleDecimal(notAvailableQty, cart.ThisCustomer.LocaleSetting)));
                        }
                        else
                        {
                            decimal computedQty = decimal.Zero;
                            computedQty = ordered - freeStock;
                            if (computedQty <= 0)
                            {
                                computedQty = ordered;
                            }
                            else
                            {
                                notAvailableQty = computedQty;
                                computedQty = ordered - notAvailableQty;
                            }
                            xmlcartItem.Add(new XElement("AVAILABLEQTY", Convert.ToInt32(computedQty)));
                            xmlcartItem.Add(new XElement("NOTAVAILABLEQTY", Convert.ToInt32(notAvailableQty))); 
                        }

                        xmlcartItem.Add(new XElement("RESERVATION_COUNT", reserveCol.Count));
                        var reservationItems = reserveCol
                                .Select(r => new XElement("RESERVATIONITEM",
                                        new XElement("RESERVE_ITEMCODE", r.ItemCode),
                                        new XElement("RESERVE_SHIPDATE", r.ShipDate.ToShortDateString()),
                                        new XElement("RESERVE_QTY", Localization.ParseLocaleDecimal(r.QtyReserved, cart.ThisCustomer.LocaleSetting))));
                        xmlcartItem.Add(reservationItems);
                    }

                    #endregion

                    #region "Unit Measure"

                    if (!hideUnitMeasure)
                    {
                        xmlcartItem.Add(new XElement("NOT_HIDE_UNIT_MEASURE", true));
                        var availableUnitMeasures = AppLogic.GetAvailableUnitMesure(cart.ThisCustomer.CustomerCode, cartItem.ItemCode, AppLogic.AppConfigBool("ShowInventoryFromAllWarehouses"), cart.ThisCustomer.IsNotRegistered);

                        if (availableUnitMeasures.Count > 1)
                        {
                            xmlcartItem.Add(new XElement("AVAILABLEUNITMESSURE_GREATER_ONE", true));
                            xmlcartItem.Add(new XElement("MULTIPLE_UNITMEASURECODENAME", "UnitMeasureCode_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));
                            xmlcartItem.Add(new XElement("MULTIPLE_UNITMEASURECODEID", "UnitMeasureCode_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));

                            foreach (var unitMeasureValue in availableUnitMeasures)
                            {
                                var unitmeasures = new XElement("UNITMEASSURE_ITEM");
                                xmlcartItem.Add(unitmeasures);
                                bool isCurrentUnitMeasureTheOneSelectedInProductPage = cartItem.UnitMeasureCode.Equals(unitMeasureValue.Key, StringComparison.InvariantCultureIgnoreCase);
                                unitmeasures.Add(new XElement("VALUE", unitMeasureValue.Key.ToHtmlEncode()));
                                unitmeasures.Add(new XElement("TEXT", unitMeasureValue.Value));
                                unitmeasures.Add(new XElement("SELECTED", isCurrentUnitMeasureTheOneSelectedInProductPage));
                                if (isCurrentUnitMeasureTheOneSelectedInProductPage)
                                {
                                    xmlcartItem.Add(new XElement("UNITMEASURECODESPANDISPLAY", unitMeasureValue.Value.ToHtmlEncode()));
                                }
                            }
                        }
                        else
                        {
                            xmlcartItem.Add(new XElement("AVAILABLEUNITMESSURE_GREATER_ONE", false));
                            xmlcartItem.Add(new XElement("UNITMEASURECODEID", "UnitMeasureCode_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));
                            xmlcartItem.Add(new XElement("UNITMEASURECODENAME", "UnitMeasureCode_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));
                            xmlcartItem.Add(new XElement("UNITMEASURECODEVALUE", cartItem.UnitMeasureCode.ToHtmlEncode()));
                            xmlcartItem.Add(new XElement("UNITMEASURECODESPANDISPLAY", availableUnitMeasures[0].Value.ToHtmlEncode()));
                        }
                    }

                    #endregion

                    #region "Input Quantities and Delete"

                    xmlcartItem.Add(new XElement("ISRESTRICTEDQUANTITIES", (cartItem.RestrictedQuantities.Count > 0)));
                    if (cartItem.RestrictedQuantities.Count > 0)
                    {
                        xmlcartItem.Add(new XElement("QUANTITYLISTID", cartItem.m_ShoppingCartRecordID));
                        xmlcartItem.Add(cartItem.RestrictedQuantities
                                    .Select(r => new XElement("RESTRICTEDQUANTITIES",
                                            new XElement("QTY", r),
                                            new XElement("SELECTED", r == cartItem.m_Quantity))));
                    }
                    else
                    {
                        xmlcartItem.Add(new XElement("INPUTQUANTITYID", "Quantity_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));
                    }

                    xmlcartItem.Add(new XElement("INPUTQUANTITYVALUE", Localization.ParseLocaleDecimal(cartItem.m_Quantity, cart.ThisCustomer.LocaleSetting)));

                    if (AppLogic.AppConfigBool("ShowCartDeleteItemButton"))
                    {
                        xmlcartItem.Add(new XElement("SHOWCARTDELETEITEMBUTTON", true));
                    }

                    xmlcartItem.Add(new XElement("MINORDERQUANTITYID", "MinOrderQuantity_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));
                    xmlcartItem.Add(new XElement("MINORDERQUANTITYNAME", "MinOrderQuantity_{0}".FormatWith(cartItem.m_ShoppingCartRecordID)));
                    xmlcartItem.Add(new XElement("MINORDERQUANTITYVALUE", cartItem.m_MinimumQuantity));

                    #endregion

                    #region "Subtotal"

                    var lineItemRow = cartItem.AssociatedLineItemRow;
                    decimal itemPrice = (decimal)lineItemRow.Table.Compute("SUM(ExtPriceRate)", string.Format("ItemCode = '{0}' AND UnitMeasureCode = '{1}'", cartItem.ItemCode, cartItem.UnitMeasureCode));
                    decimal originalAmount = (cartItem.AssociatedLineItemRow.SalesPriceRate * cartItem.AssociatedLineItemRow.QuantityOrdered);
            
                    decimal vat = decimal.Zero;
                    object vatComputed = cart.SalesOrderDataset.TransactionItemTaxDetailView.Compute("SUM(TaxAmountRate)", string.Format("ItemCode = '{0}'", cartItem.ItemCode));

                    if (vatComputed is decimal) { vat = Convert.ToDecimal(vatComputed); }

                    //added: reason -> to display sales price (no deductions) on order summary
                    xmlcartItem.Add(new XElement("SALES_PRICE", cart.ThisCustomer.FormatBasedOnMyCurrency(cartItem.AssociatedLineItemRow.SalesPriceRate)));

                    //add this if there are coupon
                    if (!coupon.IsNullOrEmptyTrimmed())
                    {
                        decimal discountAmount = originalAmount - itemPrice;

                        xmlcartItem.Add(new XElement("SALES_PRICE_RATE", cart.ThisCustomer.FormatBasedOnMyCurrency(originalAmount)));
                        xmlcartItem.Add(new XElement("COUPON_DISCOUNT_TYPE", cart.SalesOrderDataset.CustomerSalesOrderView[0][cart.SalesOrderDataset.CustomerSalesOrderView.CouponDiscountTypeColumn.ColumnName]));
                        xmlcartItem.Add(new XElement("DISCOUNT_COUPON_RATE_VALUE", string.Format("{0}", cart.ThisCustomer.FormatBasedOnMyCurrency(discountAmount))));
                        xmlcartItem.Add(new XElement("DISCOUNT_COUPON_PERCENTAGE", string.Format("{0} %", Localization.ParseLocaleDecimal(lineItemRow.CouponDiscountRate, cart.ThisCustomer.LocaleSetting))));
                    }

                    if (vatenabled && vatInclusive)
                    {
                        itemPrice += vat;
                    }

                    xmlcartItem.Add(new XElement("PRICEFORMATTED", InterpriseHelper.FormatCurrencyForCustomer(itemPrice, cart.ThisCustomer.CurrencyCode)));
                    if (vatenabled)
                    {
                        xmlcartItem.Add(new XElement("TAX_RATE_VALUE", cart.ThisCustomer.FormatBasedOnMyCurrency(vat)));
                    }

                    #endregion
                }

                //TOTAL COMPUTATION ------------------------------------------------------------------------------------//

                decimal subTotal = cart.SalesOrderDataset.CustomerSalesOrderView[0].SubTotalRate;
                decimal tax = cart.SalesOrderDataset.CustomerSalesOrderView[0].TaxRate;
                decimal freightTax = cart.SalesOrderDataset.CustomerSalesOrderView[0].FreightTaxRate;

                //breaking down the taxes to display the freight tax
                tax -= freightTax;

                decimal total = subTotal + tax;

                if (vatenabled && vatInclusive)
                {
                    subTotal += tax;
                }

                string subTotalFormatted = InterpriseHelper.FormatCurrencyForCustomer(subTotal, cart.ThisCustomer.CurrencyCode);
                if (PageRenderType == RenderType.Payment || PageRenderType == RenderType.Review)
                {
                    decimal freight = cart.SalesOrderDataset.CustomerSalesOrderView[0].FreightRate;

                    if (isFreeShipping)
                    {
                        freight = 0;
                        freightTax = 0;
                    }

                    if (vatenabled && vatInclusive)
                    {
                        freight += freightTax;
                        total += freight;
                    }
                    else
                    {
                        total += freight;
                        total += freightTax;
                    }

                    root.Add(new XElement("FREIGHT", InterpriseHelper.FormatCurrencyForCustomer(freight, cart.ThisCustomer.CurrencyCode)));
                    root.Add(new XElement("FREIGHTTAX", InterpriseHelper.FormatCurrencyForCustomer(freightTax, cart.ThisCustomer.CurrencyCode)));

                }

                root.Add(new XElement("SUBTOTAL_VALUE", subTotalFormatted));
                root.Add(new XElement("TAX_RATE_VALUE", cart.ThisCustomer.FormatBasedOnMyCurrency(tax)));
                root.Add(new XElement("TOTAL", InterpriseHelper.FormatCurrencyForCustomer(total, cart.ThisCustomer.CurrencyCode)));

                string html = string.Empty;

                if (this.CustomXmlPackage.IsNullOrEmptyTrimmed())
                {
                    html = new XmlPackage2("page.shoppingcart_items_template.xml.config", root).TransformString();
                }else{
                    html = new XmlPackage2(this.CustomXmlPackage, root).TransformString();
                }

                output.Append(html);
            }
        }


        #endregion
    }
}
